package com.sgt.frp.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import com.jcraft.jsch.JSchException;
import com.sgt.frp.VO.FrpConnect;
import com.sgt.frp.apiEnum.ApiEnum;
import com.sgt.frp.config.DomainConfig;
import com.sgt.frp.config.GlobalResponse;
import com.sgt.frp.config.LinuxConfig;
import com.sgt.frp.config.RemotePortConfig;
import com.sgt.frp.excepiton.BusinessException;
import com.sgt.frp.service.ApiService;
import com.sgt.frp.service.FrpService;
import com.sgt.frp.utils.SshUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api")
public class ApiController {

    @Autowired
    ApiService apiService;

    @Autowired
    FrpService frpService;

    @Autowired
    DomainConfig domainConfig;

    @Autowired
    RemotePortConfig remotePortConfig;

    @Autowired
    LinuxConfig linuxConfig;

    @Value("${frpServerFilePath}")
    String frpServerFilePath;

    @Value("${baseFilePath}")
    String baseFilePath;


    @GetMapping("/list")
    public GlobalResponse list(){
        List<FrpConnect> connectList = apiService.getConnectList();
        if(ObjectUtil.isEmpty(connectList)){
            return new GlobalResponse().success("当前无可用连接",null);
        }
        return new GlobalResponse().success("success",connectList);
    }

    @PostMapping("create")
    public GlobalResponse createConnect(FrpConnect frpConnect, HttpServletResponse response){

        Map<String, String> responseMap = new HashMap<>();
        String downloadUrl=null;
        try{
            Boolean creatRes = frpService.createFrpConnect(frpConnect);
        }catch (BusinessException e){
            return new GlobalResponse().fail(e.getMsg());
        }
        responseMap.put("url",downloadUrl);
        return new GlobalResponse().success("success",null);
    }

    @GetMapping("/download")
    public void download(HttpServletResponse response) throws IOException {
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("frp.zip", "UTF-8"));
        byte[] buffer = new byte[1024];
        int len;
        BufferedInputStream inputStream = FileUtil.getInputStream(baseFilePath+"frp.zip");
        OutputStream outputStream = response.getOutputStream();
        while ((len = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, len);
        }
        inputStream.close();
    }

    @GetMapping("/domain")
    public GlobalResponse domain(){
        List<String> domains = domainConfig.getDomains();
        List<String> domainsTemp = new ArrayList<>();
        domainsTemp.addAll(domains);
        List<FrpConnect> httpConnectList = apiService.getListByType(ApiEnum.HTTP_CONNECT);
        List<FrpConnect> httpsConnectList = apiService.getListByType(ApiEnum.HTTPS_CONNECT);
        if(!ObjectUtil.isEmpty(httpConnectList)){
            for (FrpConnect frpConnect : httpConnectList) {
                if(frpConnect.getCustomDomains()!=null){
                    domainsTemp.remove(frpConnect.getCustomDomains()[0]);
                }
            }
        }

        if(!ObjectUtil.isEmpty(httpsConnectList)){
            for (FrpConnect frpConnect : httpsConnectList) {
                if(frpConnect.getCustomDomains()!=null){
                    domainsTemp.remove(frpConnect.getCustomDomains()[0]);
                }
            }
        }
        return new GlobalResponse().success("success",domainsTemp);
    }
    @GetMapping("/remoteport")
    public GlobalResponse remotePort(){
        List<String> remotePortList = remotePortConfig.getRemotePortList();
        List<FrpConnect> tcpConnectList = apiService.getListByType(ApiEnum.TCP_CONNECT);
        List<FrpConnect> udpConnectList = apiService.getListByType(ApiEnum.UDP_CONNECT);
        if(!ObjectUtil.isEmpty(tcpConnectList)){
            for (FrpConnect frpConnect : tcpConnectList) {
                if(frpConnect.getRemotePort()!=null){
                    remotePortList.remove(frpConnect.getRemotePort().toString());
                }

            }
        }
        if(!ObjectUtil.isEmpty(udpConnectList)){
            for (FrpConnect frpConnect : udpConnectList) {
                if(frpConnect.getRemotePort()!=null){
                    remotePortList.remove(frpConnect.getRemotePort().toString());
                }
            }
        }
        return new GlobalResponse().success("success",remotePortList);
    }

    @GetMapping("/reset")
    public String resetFrpServer() throws JSchException {
        String cmd= "cd " + frpServerFilePath + ";  nohup ./frps -c ./frps.ini > start.log  2>&1 &";
        SshUtil.exec(linuxConfig,cmd);
        return "success";
    }

    @GetMapping("/log")
    public void log(@RequestParam(value = "time",required = false) String time, HttpServletResponse response) throws IOException {
        String logFile=null;
        if(time!=null){
            logFile="frps."+time+".log";
        }else{
            logFile="frps.log";
        }
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(logFile, "UTF-8"));
        byte[] buffer = new byte[1024];
        int len;
        BufferedInputStream inputStream = FileUtil.getInputStream(frpServerFilePath+logFile);
        OutputStream outputStream = response.getOutputStream();
        while ((len = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, len);
        }
        inputStream.close();
    }
}
